"""用户模块路由

迁移整合了原来的 users 路由，以及与用户相关的 auth 路由。
为保持稳定性，暂时继续复用现有的 schemas 与安全工具。
"""

from datetime import timedelta
from typing import List

from fastapi import APIRouter, Depends, HTTPException, status
from fastapi.security import OAuth2PasswordRequestForm
from sqlmodel import Session

from app.core.auth import (
    create_access_token,
    get_password_hash,
    verify_password,
    get_current_active_user,
    get_current_admin,
)
from app.core.config import settings
from app.core.db import get_session
from app.module.users.model import User, UserRole
from . import crud
from app.core.schemas import Token, UserCreate, AdminCreate, ChangePassword, AdminChangePassword, UserRead, UserStatusUpdate, AdminUserCreate


router = APIRouter(prefix="/users", tags=["users"])


@router.get("/me", response_model=UserRead)
def read_users_me(current_user: User = Depends(get_current_active_user)) -> UserRead:
    return UserRead(
        id=current_user.id,
        username=current_user.username,
        disabled=current_user.disabled,
        role=current_user.role,
    )


@router.get("", response_model=List[UserRead])
def list_users_api(
    _: User = Depends(get_current_admin),
    session: Session = Depends(get_session),
) -> list[UserRead]:
    users = crud.list_users(session)
    return [
        UserRead(
            id=u.id,
            username=u.username,
            disabled=u.disabled,
            role=u.role,
        )
        for u in users
    ]


@router.get("/{user_id}", response_model=UserRead)
def get_user_by_id_api(
    user_id: int,
    _: User = Depends(get_current_admin),
    session: Session = Depends(get_session),
) -> UserRead:
    user = crud.get_by_id(session, user_id)
    if user is None:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="用户不存在")
    return UserRead(
        id=user.id,
        username=user.username,
        disabled=user.disabled,
        role=user.role,
    )


@router.patch("/{user_id}/status")
def update_user_status_api(
    user_id: int,
    payload: UserStatusUpdate,
    _: User = Depends(get_current_admin),
    session: Session = Depends(get_session),
) -> dict:
    user = crud.get_by_id(session, user_id)
    if user is None:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="用户不存在")
    crud.set_disabled(session, user, payload.disabled)
    return {"ok": True}


# 删除用户（仅管理员）
@router.delete("/{user_id}")
def delete_user_api(
    user_id: int,
    _: User = Depends(get_current_admin),
    session: Session = Depends(get_session),
) -> dict:
    user = crud.get_by_id(session, user_id)
    if user is None:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="用户不存在")
    crud.delete_user(session, user)
    return {"ok": True}


@router.post("", response_model=UserRead)
def create_user_api(
    payload: AdminUserCreate,
    _: User = Depends(get_current_admin),
    session: Session = Depends(get_session),
) -> UserRead:
    existing = crud.get_by_username(session, payload.username)
    if existing is not None:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="用户名已存在")
    
    # 验证角色
    if payload.role not in ["user", "admin"]:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="无效的角色")
    
    user_role = UserRole.admin if payload.role == "admin" else UserRole.user
    
    user = crud.create_user(
        session,
        username=payload.username,
        hashed_password=get_password_hash(payload.password),
        full_name=None,  # 移除姓名字段
        role=user_role,
    )
    
    # 设置用户状态
    if payload.disabled:
        crud.set_disabled(session, user, True)
    
    return UserRead(
        id=user.id,
        username=user.username,
        disabled=user.disabled,
        role=user.role,
    )


# 兼容保留：认证相关接口（更贴近 users 模块）
auth_router = APIRouter(prefix="/auth", tags=["auth"])  # 子路由


@auth_router.post("/register", response_model=Token)
def register_user_api(payload: UserCreate, session: Session = Depends(get_session)) -> Token:
    existing = crud.get_by_username(session, payload.username)
    if existing is not None:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="用户名已存在")

    user = crud.create_user(
        session,
        username=payload.username,
        hashed_password=get_password_hash(payload.password),
        full_name=None,  # 移除姓名字段
        role=UserRole.user,
    )
    scopes = ["user:read"]
    access_token = create_access_token(data={"sub": user.username, "scopes": scopes}, expires_delta=timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES))
    return Token(access_token=access_token)


@auth_router.post("/token", response_model=Token)
def login_for_access_token_api(
    form_data: OAuth2PasswordRequestForm = Depends(),
    session: Session = Depends(get_session),
) -> Token:
    user = crud.get_by_username(session, form_data.username)
    if user is None or not verify_password(form_data.password, user.hashed_password):
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="用户名或密码错误",
            headers={"WWW-Authenticate": "Bearer"},
        )

    scopes = ["admin:read", "admin:write", "user:read"] if user.role == UserRole.admin else ["user:read"]
    access_token = create_access_token(data={"sub": user.username, "scopes": scopes}, expires_delta=timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES))
    return Token(access_token=access_token)


@auth_router.post("/change-password")
def change_password_api(
    payload: ChangePassword,
    current_user: User = Depends(get_current_active_user),
    session: Session = Depends(get_session),
) -> dict:
    if not verify_password(payload.current_password, current_user.hashed_password):
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="当前密码错误")
    crud.set_password(session, current_user, get_password_hash(payload.new_password))
    return {"ok": True}


@auth_router.post("/admin/register", response_model=Token)
def admin_register_api(
    payload: AdminCreate,
    _: User = Depends(get_current_admin),
    session: Session = Depends(get_session),
) -> Token:
    existing = crud.get_by_username(session, payload.username)
    if existing is not None:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="用户名已存在")
    user = crud.create_user(
        session,
        username=payload.username,
        hashed_password=get_password_hash(payload.password),
        full_name=None,  # 移除姓名字段
        role=UserRole.admin,
    )
    scopes = ["admin:read", "admin:write", "user:read"]
    access_token = create_access_token(data={"sub": user.username, "scopes": scopes}, expires_delta=timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES))
    return Token(access_token=access_token)


@auth_router.post("/admin/change-password")
def admin_change_password_api(
    payload: AdminChangePassword,
    _: User = Depends(get_current_admin),
    session: Session = Depends(get_session),
) -> dict:
    user = crud.get_by_username(session, payload.username)
    if user is None:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="用户不存在")
    crud.set_password(session, user, get_password_hash(payload.new_password))
    return {"ok": True}


@auth_router.get("/verify")
def verify_token_api(_: User = Depends(get_current_active_user)) -> dict:
    return {"valid": True}


